﻿using JNPF.Basics.Logic;
using JNPF.Basics.Logic.Common.Login;
using JNPF.Basics.Models;
using JNPF.Basics.Models.Permission.Dtos.UsersCurrent;
using JNPF.Basics.Models.Permission.Model;
using JNPF.Utils;
using JNPF.Utils.Controller;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace JNPF.Basics.Controller.Permission
{
    /// <summary>
    /// 个人资料
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// 日 期：2017.12.18 
    /// </summary>
    [Route("api/Permission/Users/Current")]
    public class UsersCurrentController : BaseApiController
    {
        private UserBll userBll = new UserBll();
        private OrganizeBll organizeBll = new OrganizeBll();
        private PositionBll positionBll = new PositionBll();
        private RoleBll roleBll = new RoleBll();
        private LoginBll loginBll = new LoginBll();
        private LogBll logBll = new LogBll();

        #region Get
        /// <summary>
        /// 获取我的下属
        /// </summary>
        /// <returns></returns>
        [HttpGet("Subordinate")]
        public async Task<ResponseResult> GetSubordinate()
        {
            var outputList = new List<UsersCurrentSubordinateOutput>();
            UserInfo userInfo = UserProvider.Instance.Get();
            List<string> subordinateIds = new List<string>(userInfo.SubordinateIds);
            var userList = await userBll.GetList();
            var organizeList = await organizeBll.GetList();
            foreach (var item in subordinateIds)
            {
                var output = new UsersCurrentSubordinateOutput();
                var userEntity = userList.Find(u => u.Id == item);
                output.avatar = "/api/Common/Image/userAvatar/" + userEntity.HeadIcon;
                output.department = organizeList.Find(o => o.Id == userEntity.OrganizeId).FullName;
                output.userName = userEntity.RealName + "/" + userEntity.Account;
                outputList.Add(output);
            }
            return Success(outputList);
        }

        /// <summary>
        /// 获取个人资料
        /// </summary>
        /// <returns></returns>
        [HttpGet("BaseInfo")]
        public async Task<ResponseResult> GetBaseInfo()
        {
            UserInfo userInfo = UserProvider.Instance.Get();
            var data = await userBll.GetInfo(userInfo.UserId);
            var output = data.MapTo<UsersCurrentInfoOutput>();
            output.organize = (await organizeBll.GetInfo(data.OrganizeId)).Category.Equals("department") ? (await organizeBll.GetInfo(data.OrganizeId)).FullName : "";
            output.company = await this.GetCompany(data.OrganizeId);
            output.position = positionBll.GetName(data.PositionId);
            output.roleId = roleBll.GetName(data.RoleId);
            output.manager = userBll.GetUserName(data.ManagerId);
            return Success(output);
        }

        /// <summary>
        /// 获取系统权限
        /// </summary>
        /// <returns></returns>
        [HttpGet("Authorize")]
        public async Task<ResponseResult> GetAuthorize()
        {
            var LoginCurrentUserModel = await loginBll.GetAuthorize();
            var output = new UsersCurrentAuthorizeOutput();
            if (LoginCurrentUserModel.moduleList.Count != 0)
            {
                output.module = LoginCurrentUserModel.moduleList.MapToList<UsersCurrentAuthorizeMoldel>().ToTree("-1");
            }
            if (LoginCurrentUserModel.buttonList.Count != 0)
            {
                LoginCurrentUserModel.buttonList.ForEach(b =>
                {
                    if (b.ParentId.Equals("-1"))
                    {
                        b.ParentId = b.ModuleId;
                    }
                });
                var menuAuthorizeData = new List<UsersCurrentAuthorizeMoldel>();
                var pids = LoginCurrentUserModel.buttonList.Select(bt => bt.ModuleId).ToList().Distinct().ToList();
                GetParentsModuleList(pids, LoginCurrentUserModel.moduleList, ref menuAuthorizeData);
                output.button = LoginCurrentUserModel.buttonList.MapToList<UsersCurrentAuthorizeMoldel>().Union(menuAuthorizeData).ToList().ToTree("-1");
            }
            if (LoginCurrentUserModel.columnList.Count != 0)
            {
                LoginCurrentUserModel.columnList.ForEach(b =>
                {
                    b.ParentId = b.ModuleId;
                });
                var menuAuthorizeData = new List<UsersCurrentAuthorizeMoldel>();
                var pids = LoginCurrentUserModel.columnList.Select(bt => bt.ModuleId).ToList().Distinct().ToList();
                GetParentsModuleList(pids, LoginCurrentUserModel.moduleList, ref menuAuthorizeData);
                output.column = LoginCurrentUserModel.columnList.MapToList<UsersCurrentAuthorizeMoldel>().Union(menuAuthorizeData).ToList().ToTree("-1");
            }
            if (LoginCurrentUserModel.resourceList.Count != 0)
            {
                var resourceData = LoginCurrentUserModel.resourceList.Select(r => new UsersCurrentAuthorizeMoldel
                {
                    id = r.Id,
                    parentId = r.ModuleId,
                    fullName = r.FullName,
                    icon = "icon-ym icon-ym-extend"
                }).ToList();
                var menuAuthorizeData = new List<UsersCurrentAuthorizeMoldel>();
                var pids = LoginCurrentUserModel.resourceList.Select(bt => bt.ModuleId).ToList().Distinct().ToList();
                GetParentsModuleList(pids, LoginCurrentUserModel.moduleList, ref menuAuthorizeData);
                output.resource = resourceData.Union(menuAuthorizeData).ToList().ToTree("-1");
            }
            return Success(output);
        }

        /// <summary>
        /// 获取系统日志
        /// </summary>
        /// <returns></returns>
        [HttpGet("SystemLog")]
        public async Task<ResponseResult> GetSystemLog([FromQuery] UsersCurrentSystemLogQuery input)
        {
            UserInfo userInfo = UserProvider.Instance.Get();
            var requestParam = input.MapTo<PageInput>();
            requestParam.queryJson = new { input.startTime, input.endTime }.ToJson();
            var dataLog = await logBll.GetList(input.category, requestParam);
            dataLog.list = dataLog.list.FindAll(l => l.UserId == userInfo.UserId);
            dataLog.pagination.total = dataLog.list.Count;
            var output = new PageResult<UsersCurrentSystemLogOutput>
            {
                list = dataLog.list.MapToList<UsersCurrentSystemLogOutput>(),
                pagination = dataLog.pagination
            };
            return Success(output);
        }
        #endregion

        #region Post
        /// <summary>
        /// 修改密码
        /// </summary>
        /// <returns></returns>
        [HttpPost("Actions/ModifyPassword")]
        public async Task<ResponseResult> ModifyPassword([FromBody] UsersCurrentActionsModifyPasswordInput input)
        {
            UserInfo userInfo = UserProvider.Instance.Get();
            var data = await userBll.GetInfo(userInfo.UserId);
            if (Md5Helper.md5(input.oldPassword.ToLower() + data.Secretkey).ToLower() != data.Password.ToLower())
                return Error("旧密码错误，请重新输入");
            //获取缓存验证码
            var imageCode = CacheFactory.Cache.Get(CacheKey.VALIDCODE + CacheFactory.Cache.Get("timestamp"));
            if (!input.code.ToLower().Equals(imageCode))
            {
                return Error("验证码错误");
            }
            else
            {
                CacheFactory.Cache.Remove(CacheKey.VALIDCODE + CacheFactory.Cache.Get("timestamp"));
                CacheFactory.Cache.Remove("timestamp");
            }
            data.Password = Md5Helper.md5(input.password + data.Secretkey);
            await userBll.Update(data.Id, data);
            UserProvider.Instance.Remove();
            return Success("修改成功，请牢记新密码。");
        }

        /// <summary>
        /// 修改个人资料
        /// </summary>
        /// <returns></returns>
        [HttpPut("BaseInfo")]
        public async Task<ResponseResult> UpdateBaseInfo([FromBody] UsersCurrentInfoUpInput input)
        {
            UserInfo userInfo = UserProvider.Instance.Get();
            var data = await userBll.GetInfo(userInfo.UserId);
            var entity = InputToEntity(input, data);
            await userBll.Update(data.Id, entity);
            return Success("修改成功");
        }

        /// <summary>
        /// 修改主题
        /// </summary>
        /// <returns></returns>
        [HttpPut("SystemTheme")]
        public async Task<ResponseResult> UpdateBaseInfo([FromBody] string input)
        {
            UserInfo userInfo = UserProvider.Instance.Get();
            var data = await userBll.GetInfo(userInfo.UserId);
            data.Theme = input;
            await userBll.Update(data.Id, data);
            return Success("修改成功");
        }

        /// <summary>
        /// 修改系统语言
        /// </summary>
        /// <returns></returns>
        [HttpPut("SystemLanguage")]
        public async Task<ResponseResult> UpdateLanguage([FromBody] string input)
        {
            UserInfo userInfo = UserProvider.Instance.Get();
            var data = await userBll.GetInfo(userInfo.UserId);
            data.Language = input;
            await userBll.Update(data.Id, data);
            return Success("修改成功");
        }
        #endregion

        #region Method
        /// <summary>
        /// 获取公司名称
        /// </summary>
        /// <param name="OrganizeId">id</param>
        /// <returns></returns>
        private async Task<string> GetCompany(string OrganizeId)
        {
            var data = await organizeBll.GetInfo(OrganizeId);
            if (data == null || string.IsNullOrEmpty(data.Category))
            {
                return "";
            }
            if (data.Category.Equals("department"))
            {
                return await GetCompany(data.ParentId);
            }
            else
            {
                return data.FullName;
            }
        }

        /// <summary>
        /// 过滤菜单权限数据
        /// </summary>
        /// <param name="pids">其他权限数据</param>
        /// <param name="moduleList">勾选菜单权限数据</param>
        /// <param name="output">返回值</param>
        private void GetParentsModuleList(List<string> pids, List<ModuleEntity> moduleList, ref List<UsersCurrentAuthorizeMoldel> output)
        {
            var authorizeModuleData = moduleList.MapToList<UsersCurrentAuthorizeMoldel>();
            foreach (var item in pids)
            {
                GteModuleListById(item, authorizeModuleData, output);
            }
            output = output.Distinct().ToList();
        }

        /// <summary>
        /// 根据菜单id递归获取authorizeDataOutputModel的父级菜单
        /// </summary>
        /// <param name="id">菜单id</param>
        /// <param name="authorizeModuleData">选中菜单集合</param>
        /// <param name="output">返回数据</param>
        private void GteModuleListById(string id, List<UsersCurrentAuthorizeMoldel> authorizeModuleData, List<UsersCurrentAuthorizeMoldel> output)
        {
            var data = authorizeModuleData.Find(l => l.id == id);
            if (data != null)
            {
                if (data.parentId != "-1")
                {
                    if (!output.Contains(data))
                    {
                        output.Add(data);
                    }
                    GteModuleListById(data.parentId, authorizeModuleData, output);
                }
                else
                {
                    if (!output.Contains(data))
                    {
                        output.Add(data);
                    }
                }
            }
        }

        /// <summary>
        /// 参数转换数据库实体
        /// </summary>
        /// <param name="input"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        private UserEntity InputToEntity(UsersCurrentInfoUpInput input, UserEntity entity)
        {
            entity.Birthday = input.birthday == 0 ? DateTime.Now : CommonHelper.GetDateTime(input.birthday.ToString());
            entity.CertificatesNumber = input.certificatesNumber;
            entity.CertificatesType = input.certificatesType;
            entity.Education = input.education;
            entity.Email = input.email;
            entity.Gender = input.gender.ToInt();
            entity.Landline = input.landline;
            entity.MobilePhone = input.mobilePhone;
            entity.Nation = input.nation;
            entity.NativePlace = input.nativePlace;
            entity.PostalAddress = input.postalAddress;
            entity.RealName = input.realName;
            entity.Signature = input.signature;
            entity.TelePhone = input.telePhone;
            entity.UrgentContacts = input.urgentContacts;
            entity.UrgentTelePhone = input.urgentTelePhone;
            return entity;
        }
        #endregion
    }
}
